package com.ratelimit.redis.redis.sharedPool;

import org.junit.Test;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import java.util.Arrays;
import java.util.List;

/**
 * ShardedJedis：分布式分片方式实现缓存
 * ShardedJedis是通过一致性哈希来实现分布式缓存的，通过一定的策略把不同的key分配到不同的redis server上，达到横向扩展的目的。
 **/
public class SimpleShardedPoolDemo {

    private static ShardedJedisPool shardedPool = null;

    /**
     * setMinIdle() :应该在池中始终保持的最小已建立连接数。
     * setMaxIdle() :空闲时候池中始终保持的最大建立连接数。
     * setMaxActive()：可以同时从此池中分配的活动连接的最大数目。缺省值是100
     * setInitialSize()：设置连接池启动时将建立的连接数。默认值为10。如果这个值超过setMaxActive(int)，它将自动降低。
     */
    public static ShardedJedis getShardedPool() {
        if (shardedPool == null) {
            synchronized (SimpleShardedPoolDemo.class) {
                if (shardedPool == null) {

                    JedisPoolConfig config = new JedisPoolConfig();
                    config.setMaxTotal(500);
                    config.setMaxIdle(5);
                    config.setMaxWaitMillis(1000 * 10);
                    //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
                    config.setTestOnBorrow(true);


                    //设置Redis信息
                    String host = "127.0.0.1";
                    JedisShardInfo shardInfo1 = new JedisShardInfo(host, 6379, 500);
                    shardInfo1.setPassword("test123");
                    JedisShardInfo shardInfo2 = new JedisShardInfo(host, 6380, 500);
                    shardInfo2.setPassword("test123");
                    JedisShardInfo shardInfo3 = new JedisShardInfo(host, 6381, 500);
                    shardInfo3.setPassword("test123");

                    //初始化ShardedJedisPool
                    List<JedisShardInfo> infoList = Arrays.asList(shardInfo1, shardInfo2, shardInfo3);
                    ShardedJedisPool pool = new ShardedJedisPool(config, infoList);
                    shardedPool = pool;

                }

            }
        }
        return shardedPool.getResource();

    }


    @Test
    public void testCRUD() {
        ShardedJedis redis = null;
        int loop = 1;
        while (loop < 20) {
            try {
                long start = System.currentTimeMillis();
                redis = getShardedPool();
                redis.set("k1", "v1");
                String ret = redis.get("k1");
                long end = System.currentTimeMillis();
                System.out.printf("Get ret from redis: %s with %d millis\n", ret, end - start);
            } finally {
                //使用后一定关闭，还给连接池

                if (redis != null) {
                    redis.close();
                }
            }
            loop++;
        }
    }

}
